home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 284_01 / mkhex.c < prev    next >
Text File  |  1989-03-11  |  3KB  |  147 lines

  1. /* mkhex.c - make CPMnn.HEX file */
  2.  
  3. #include <stdio.h>
  4.  
  5. #define COPYRIGHT    "Copyright (C) 1979 Digital Research"
  6.  
  7. #define LENGTH        0x1600
  8. #define RECORD        32
  9.  
  10. unsigned char sum;
  11.  
  12. puthex ( b, fp )
  13.     unsigned char b;
  14.     FILE * fp;
  15. {
  16.     fprintf( fp, "%02X", b );
  17.     sum += b;
  18. }
  19.  
  20. main ( argc, argv )
  21.     int argc;
  22.     char * argv [];
  23. {
  24.     FILE * ifp, * ofp;
  25.     char ifid [ 14 ], ofid [ 14 ], bfid [ 14 ];
  26.     unsigned base, size;
  27.     int n, i, c;
  28.  
  29.     /* check command syntax */
  30.     if ( argc != 2 ) {
  31.         fprintf( stderr, "usage: mkhex size\n" );
  32.         return( 2 );
  33.     }
  34.  
  35.     /* get CP/M size in KB */
  36.     size = atoi( argv[ 1 ] );
  37.     if ( size < 20 ) {
  38.         fprintf( stderr, "%dKB is too small; min. 20KB\n", size );
  39.         return( 2 );
  40.     }
  41.     if ( size > 64 ) {
  42.         fprintf( stderr, "%dKB is too large; max. 64KB\n", size );
  43.         return( 2 );
  44.     }
  45.  
  46.     /* find file names */
  47.     sprintf( ifid, "CPM%2d.COM",  size );
  48.     sprintf( ofid, "CPM%2d.HEX",  size );
  49.     sprintf( bfid, "BIOS%2d.HEX", size );
  50.  
  51.     /* find base address of CP/M system */
  52.     base = 0x3400 + ( size - 20 ) * 1024;
  53.  
  54.     /* open output file */
  55.     ofp = fopen( ofid, "w" );
  56.     if ( ofp == NULL ) {
  57.         fprintf( stderr, "cannot open %s for output\n", ofid );
  58.         return( 1 );
  59.     }
  60.  
  61.     /* open CP/M image file */
  62.     ifp = fopen( ifid, "rb" );
  63.     if ( ifp == NULL ) {
  64.         fprintf( stderr, "cannot open %s for input\n", ifid );
  65.         return( 1 );
  66.     }
  67.  
  68.     /* skip garbage */
  69.     if ( fseek( ifp, 0x0880L, 0 ) ) {
  70.         fprintf( stderr, "cannot seek to 0980H of %s\n", ifid );
  71.         return( 1 );
  72.     }
  73.  
  74.     /* output title */
  75.     fprintf( ofp, "# %dKB CP/M-80 ver. 2.2, %s\n", size, COPYRIGHT );
  76.  
  77.     /* generate Intel HEX format */
  78.     for ( n = 0; n < LENGTH; n += RECORD ) {
  79.  
  80.         /* clear check sum */
  81.         sum = 0;
  82.  
  83.         /* output a record header */
  84.         putc( ':', ofp );
  85.         puthex( RECORD, ofp );
  86.         puthex( ( n + base ) >> 8,   ofp );
  87.         puthex( ( n + base ) & 0xFF, ofp );
  88.         puthex( 0, ofp );
  89.  
  90.         /* output data */
  91.         for ( i = 0; i < RECORD; i++ ) {
  92.             puthex( getc( ifp ), ofp );
  93.         }
  94.  
  95.         /* output check sum and trailer */
  96.         puthex( ( -sum ) & 0xFF, ofp );
  97.         putc( '\n', ofp );
  98.     }
  99.  
  100.     /* close input file */
  101.     if ( feof( ifp ) ) {
  102.         fprintf( stderr, "file %s is too short\n", ifid );
  103.         return( 1 );
  104.     }
  105.     if ( ferror( ifp ) ) {
  106.         fprintf( stderr, "file read error on %s\n", ifid );
  107.         return( 1 );
  108.     }
  109.     if ( fclose( ifp ) ) {
  110.         fprintf( stderr, "cannot close file %s\n", ifid );
  111.         return( 1 );
  112.     }
  113.  
  114.     /* open BIOS file */
  115.     ifp = fopen( bfid, "r" );
  116.     if ( ifp == NULL ) {
  117.         fprintf( stderr, "cannot open %s for input\n", bfid );
  118.         return( 1 );
  119.     }
  120.  
  121.     /* copy BIOS file */
  122.     fprintf( ofp, "# %dKB BIOS image\n", size );
  123.     while ( ( c = getc( ifp ) ) != EOF ) putc( c, ofp );
  124.  
  125.     /* close BIOS file */
  126.     if ( ferror( ifp ) ) {
  127.         fprintf( stderr, "file read error on %s\n", bfid );
  128.         return( 1 );
  129.     }
  130.     if ( fclose( ifp ) ) {
  131.         fprintf( stderr, "cannot close file %s\n", bfid );
  132.         return( 1 );
  133.     }
  134.  
  135.     /* close CP/M image file */
  136.     if ( ferror( ofp ) ) {
  137.         fprintf( stderr, "file write error on %s\n", ofid );
  138.         return( 1 );
  139.     }
  140.     if ( fclose( ofp ) ) {
  141.         fprintf( stderr, "cannot close file %s\n", ofid );
  142.         return( 1 );
  143.     }
  144.  
  145.     return( 0 );
  146. }
  147.